// Copyright Epic Games, Inc. All Rights Reserved. // 版权声明，Epic Games公司保留所有权利

#include "LyraGameplayEffectContext.h" // 包含对应的头文件

#include "AbilitySystem/LyraAbilitySourceInterface.h" // 包含能力源接口的头文件
#include "Engine/HitResult.h" // 包含命中结果的头文件
#include "PhysicalMaterials/PhysicalMaterial.h" // 包含物理材质的头文件

#if UE_WITH_IRIS // 如果启用了Iris网络同步系统（编译条件）
#include "Iris/ReplicationState/PropertyNetSerializerInfoRegistry.h" // 包含Iris属性网络序列化信息注册表的头文件
#include "Serialization/GameplayEffectContextNetSerializer.h" // 包含GameplayEffectContext网络序列化器的头文件
#endif // 结束条件编译

#include UE_INLINE_GENERATED_CPP_BY_NAME(LyraGameplayEffectContext) // 包含由UHT生成的内联函数代码

class FArchive; // 前向声明FArchive类（在.cpp中再次前向声明，有时是为了解决编译依赖）

/** 
 * 从FGameplayEffectContextHandle中提取出封装的FLyraGameplayEffectContext指针
 * @param Handle 游戏效果上下文句柄
 * @return 成功则返回FLyraGameplayEffectContext指针，失败（不存在或类型错误）则返回nullptr
 */
FLyraGameplayEffectContext* FLyraGameplayEffectContext::ExtractEffectContext(struct FGameplayEffectContextHandle Handle) // 静态成员函数的定义
{
	FGameplayEffectContext* BaseEffectContext = Handle.Get(); // 从句柄中获取基础的游戏效果上下文指针
	if ((BaseEffectContext != nullptr) && BaseEffectContext->GetScriptStruct()->IsChildOf(FLyraGameplayEffectContext::StaticStruct())) // 检查指针非空且其脚本结构体是FLyraGameplayEffectContext或其子类
	{
		return (FLyraGameplayEffectContext*)BaseEffectContext; // 安全地将基础指针转换（向下转型）为FLyraGameplayEffectContext指针并返回
	}

	return nullptr; // 如果检查失败，返回空指针
}

/** 
 * 网络序列化函数，用于在网络上发送和接收此上下文数据
 * @param Ar 存档对象，用于序列化数据
 * @param Map 包映射，用于处理对象引用的序列化
 * @param bOutSuccess 输出参数，表示序列化是否成功
 * @return 总是返回true
 */
bool FLyraGameplayEffectContext::NetSerialize(FArchive& Ar, class UPackageMap* Map, bool& bOutSuccess) // 成员函数的定义
{
	FGameplayEffectContext::NetSerialize(Ar, Map, bOutSuccess); // 首先调用父类的NetSerialize函数，序列化继承的字段

	// 以下注释说明：CartridgeID 不为激活后使用而序列化（意味着它可能只在服务器端计算或使用，不通过网络发送到客户端）
	// CartridgeID

	return true; // 返回true表示序列化过程完成（无错误）
}

#if UE_WITH_IRIS // 如果启用了Iris网络同步系统（编译条件）
namespace UE::Net // 进入UE::Net命名空间
{
	// 注释说明：转发给FGameplayEffectContextNetSerializer进行处理
	// 注意：如果修改了FLyraGameplayEffectContext::NetSerialize()，则必须实现自定义的NetSerializer，因为当前的转发回退将不再足够。
	UE_NET_IMPLEMENT_FORWARDING_NETSERIALIZER_AND_REGISTRY_DELEGATES(LyraGameplayEffectContext, FGameplayEffectContextNetSerializer); // 宏，为Iris系统注册一个转发网络序列化器，将FLyraGameplayEffectContext的序列化工作委托给FGameplayEffectContextNetSerializer
}
#endif // 结束条件编译

/** 
 * 设置用作能力源的对象
 * @param InObject 实现了ILyraAbilitySourceInterface接口的对象
 * @param InSourceLevel 源等级
 */
void FLyraGameplayEffectContext::SetAbilitySource(const ILyraAbilitySourceInterface* InObject, float InSourceLevel) // 成员函数的定义
{
	AbilitySourceObject = MakeWeakObjectPtr(Cast<const UObject>(InObject)); // 将传入的接口指针转换为UObject指针，并创建一个弱对象指针赋给AbilitySourceObject成员（避免循环引用导致的内存泄漏）
	//SourceLevel = InSourceLevel; // 这行代码被注释掉了，说明SourceLevel成员可能已被移除或暂时不使用
}

/** 
 * 获取与源对象关联的能力源接口
 * @return 返回能力源接口指针，仅在权威端有效
 */
const ILyraAbilitySourceInterface* FLyraGameplayEffectContext::GetAbilitySource() const // 成员函数的定义
{
	return Cast<ILyraAbilitySourceInterface>(AbilitySourceObject.Get()); // 从弱指针获取UObject指针，并尝试转换为ILyraAbilitySourceInterface接口指针后返回
}

/** 
 * 从命中结果中获取物理材质
 * @return 如果存在命中结果且其包含物理材质，则返回该物理材质指针，否则返回nullptr
 */
const UPhysicalMaterial* FLyraGameplayEffectContext::GetPhysicalMaterial() const // 成员函数的定义
{
	if (const FHitResult* HitResultPtr = GetHitResult()) // 获取上下文中存储的命中结果指针，并检查其有效性
	{
		return HitResultPtr->PhysMaterial.Get(); // 从命中结果中获取物理材质弱指针，并通过Get()方法转换为强指针返回
	}
	return nullptr; // 如果没有有效的命中结果，返回空指针
}